/**
  ******************************************************************************
  * @file    pid_driver.c
  * @author  Sherlock
  * @version V0.1
  * @date    08/12/2024
  * @brief   PID driver.
  ******************************************************************************
  * @copy
  *
  * <h2><center>&copy; COPYRIGHT 2010 Feirui</center></h2>
  */ 



/**
  * @brief  INCLUDE FILES.
  */
#ifndef	PID_DRIVER_GLOBAL
#define	PID_DRIVER_GLOBAL
#include <includes.h>
#include "pid_driver.h"
#include "pid_cfg.h"


static uint8_t PID_HWInit_RCC(void);
static uint8_t PID_HWInit_TIM(void);
static uint8_t PID_HWInit_GPIO(void);

uint8_t PID_HWInit(void)
{
	uint8_t status = DEF_FALSE;

	status |= PID_HWInit_RCC();
	status |= PID_HWInit_TIM();
	status |= PID_HWInit_GPIO();

	return DEF_TRUE;
}


uint8_t PID_HWEnable(void)
{
	TIM_Enable(PIDTIM, ENABLE);
	TIM_Enable(PIDTIM4, ENABLE);
    
	return DEF_TRUE;
}


static uint8_t PID_HWInit_RCC(void)
{
	RCC_EnableAPB2PeriphClk(PIDTIM_RCCPeriph, ENABLE);
	RCC_EnableAPB1PeriphClk(PIDTIM4_RCCPeriph, ENABLE);
	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);

	/* Enable GPIOx clock */
	uint32_t RCC_APBxPeriph_GPIOx;
	uint8_t i;
	for(i = 0, RCC_APBxPeriph_GPIOx = 0; i < PIDGPIOPortCfgNumber; i++)
		RCC_APBxPeriph_GPIOx |= PIDGPIOPortCfgTbl[i].RCC_APB2Periph;
	RCC_EnableAPB2PeriphClk(RCC_APBxPeriph_GPIOx, ENABLE);
    
	return DEF_TRUE;
}

static uint8_t PID_HWInit_TIM(void)
{
	OCInitType TIM_OCInitStructure;
	TIM_TimeBaseInitType TIM_TimeBaseStructure;
	
	/* TIM config */
	/* Choose Internal Clock */
	TIM_ConfigInternalClk(PIDTIM);
	
	/* Time Base configuration */
	TIM_TimeBaseStructure.Prescaler = PIDTIM_Prescaler        ;
	TIM_TimeBaseStructure.CntMode   = PIDTIM_CounterMode      ;
	TIM_TimeBaseStructure.Period    = PIDTIM_Period           ;
	TIM_TimeBaseStructure.ClkDiv    = PIDTIM_ClockDivision    ;
	TIM_TimeBaseStructure.RepetCnt  = PIDTIM_RepetitionCounter;
	TIM_InitTimeBase(PIDTIM, &TIM_TimeBaseStructure);
	
	/* Output Compare Active Mode configuration: Channel2 */
	TIM_OCInitStructure.OcMode       = PIDTIM_OCMode      ;
	TIM_OCInitStructure.OutputState  = PIDTIM_OutputState ;
	TIM_OCInitStructure.OutputNState = PIDTIM_OutputNState;
	TIM_OCInitStructure.Pulse        = PIDTIM_Pulse       ;
	TIM_OCInitStructure.OcPolarity   = PIDTIM_OCPolarity  ;
	TIM_OCInitStructure.OcNPolarity  = PIDTIM_OCNPolarity ;
	TIM_OCInitStructure.OcIdleState  = PIDTIM_OCIdleState ;
	TIM_OCInitStructure.OcNIdleState = PIDTIM_OCNIdleState;
	TIM_InitOc1(PIDTIM, &TIM_OCInitStructure);
	/* Enable reload CR2 after EVENT */
	TIM_ConfigOc1Preload(PIDTIM, TIM_OC_PRE_LOAD_DISABLE);

	TIM_EnableCtrlPwmOutputs(PIDTIM, ENABLE);

	/* TIM4 */
	/* Choose Internal Clock */
	TIM_ConfigInternalClk(PIDTIM4);
	
	/* Time Base configuration */
	TIM_TimeBaseStructure.Prescaler = PIDTIM4_Prescaler        ;
	TIM_TimeBaseStructure.CntMode   = PIDTIM4_CounterMode      ;
	TIM_TimeBaseStructure.Period    = PIDTIM4_Period           ;
	TIM_TimeBaseStructure.ClkDiv    = PIDTIM4_ClockDivision    ;
	TIM_TimeBaseStructure.RepetCnt  = PIDTIM4_RepetitionCounter;
	TIM_InitTimeBase(PIDTIM4, &TIM_TimeBaseStructure);
	
	/* Output Compare Active Mode configuration: Channel2 */
	TIM_OCInitStructure.OcMode       = PIDTIM4_OCMode      ;
	TIM_OCInitStructure.OutputState  = PIDTIM4_OutputState ;
	TIM_OCInitStructure.OutputNState = PIDTIM4_OutputNState;
	TIM_OCInitStructure.Pulse        = PIDTIM4_Pulse       ;
	TIM_OCInitStructure.OcPolarity   = PIDTIM4_OCPolarity  ;
	TIM_OCInitStructure.OcNPolarity  = PIDTIM4_OCNPolarity ;
	TIM_OCInitStructure.OcIdleState  = PIDTIM4_OCIdleState ;
	TIM_OCInitStructure.OcNIdleState = PIDTIM4_OCNIdleState;
	TIM_InitOc4(PIDTIM4, &TIM_OCInitStructure);
	/* Enable reload CR2 after EVENT */
	TIM_ConfigOc4Preload(PIDTIM4, TIM_OC_PRE_LOAD_DISABLE);

	TIM_ConfigArPreload(PIDTIM4, ENABLE);
	
	return DEF_TRUE;
}


static uint8_t PID_HWInit_GPIO(void)
{
	GPIO_InitType GPIO_InitStructure;

	/* Configuration Port for ADC pin */
	GPIO_InitStruct(&GPIO_InitStructure);
	for(uint8_t i = 0; i < PIDGPIOPortCfgNumber; i++)
	{
		GPIO_InitStructure.Pin = PIDGPIOPortCfgTbl[i].GPIO_Pin;
		GPIO_InitStructure.GPIO_Speed = PIDGPIOPortCfgTbl[i].GPIO_Speed;
		GPIO_InitStructure.GPIO_Mode  = PIDGPIOPortCfgTbl[i].GPIO_Mode;
		GPIO_InitPeripheral(PIDGPIOPortCfgTbl[i].GPIOx, &GPIO_InitStructure);
	}
	GPIO_ConfigPinRemap(PIDGPIO_OutputPinRemap, ENABLE);   //部分重映象
	GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE);   //部分重映象

	return DEF_TRUE;
}


#endif	/*	PID_DRIVER_GLOBAL	*/

/******************* (C) COPYRIGHT 2010 Feirui *****END OF FILE****/